﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using D2DEngine.Scene;
using Microsoft.Xna.Framework.Graphics;

namespace D2DEngine
{
    public class D2DAnimatedSpriteComponent : D2DGraphicsComponent
    {        
        string currentAnimation = null;
        bool animating = true;        

        /// <summary>
        /// The collection of animations in the animated sprite
        /// </summary>
        public Dictionary<string, D2DFrameAnimation> Animations =
            new Dictionary<string, D2DFrameAnimation>();

        /// <summary>
        /// The source rectangle on the image corresponding
        /// to the current animation.
        /// </summary>
        public override Rectangle? SourceRect
        {
            get { return CurrentAnimation.CurrentRect; }
        }

        /// <summary>
        /// The width of the current animation
        /// </summary>
        public override int Width
        {
            get { return CurrentAnimation.CurrentRect.Width; }
        }

        /// <summary>
        /// The height of the current animation
        /// </summary>
        public override int Height
        {
            get { return CurrentAnimation.CurrentRect.Height; }
        }

        /// <summary>
        /// Is the animation animating ?
        /// </summary>
        public bool IsAnimating
        {
            get { return animating; }
            set { animating = value; }
        }

        /// <summary>
        /// The current animation
        /// </summary>
        public D2DFrameAnimation CurrentAnimation
        {
            get
            {
                if (!string.IsNullOrEmpty(currentAnimation))
                    return Animations[currentAnimation];
                else
                    return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string CurrentAnimationName
        {
            get { return currentAnimation; }
            set
            {
                if (Animations.ContainsKey(value))
                    currentAnimation = value;
            }
        }

        public D2DAnimatedSpriteComponent(Texture2D texture)
            : base(texture)
        {
        }

        public D2DAnimatedSpriteComponent()
        {
        }

        /// <summary>
        /// Adds an animation to the animated sprite
        /// </summary>
        /// <param name="name">The name of the animation</param>
        /// <param name="frames">The number of consecutive frames in this animation</param>
        /// <param name="x">The X coordinate of the first frame</param>
        /// <param name="y">The Y coordinate of the first frame</param>
        /// <param name="width">The width of the frame</param>
        /// <param name="height">The height of the frame</param>
        public void AddAnimation(string name, int frames, int x, int y, int width, int height)
        {
            this.Animations.Add(name, new D2DFrameAnimation(frames, x, y, width, height));
        }

        /// <summary>
        /// Adds an animation to the animated sprite
        /// </summary>
        /// <param name="name">The name of the animation</param>
        /// <param name="frames">The number of consecutive frames in this animation</param>
        /// <param name="x">The X coordinate of the first frame</param>
        /// <param name="y">The Y coordinate of the first frame</param>
        /// <param name="width">The width of the frame</param>
        /// <param name="height">The height of the frame</param>
        /// <param name="frameLength">The length of this animation in seconds</param>
        public void AddAnimation(string name, int frames, int x, int y, int width, int height, float frameLength)
        {
            this.Animations.Add(name, new D2DFrameAnimation(frames, x, y, width, height, frameLength));
        }
        
        /// <summary>
        /// Updates the animated sprite
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            if (!IsAnimating)
                return;

            D2DFrameAnimation animation = CurrentAnimation;

            if (animation == null)
            {
                if (Animations.Count > 0)
                {
                    string[] keys = new string[Animations.Count];
                    Animations.Keys.CopyTo(keys, 0);

                    currentAnimation = keys[0];

                    animation = CurrentAnimation;
                }
                else
                    return;
            }

            animation.Update(gameTime);


            base.Update(gameTime);
        }



        /// <summary>
        /// Copies the animated sprite
        /// </summary>
        /// <param name="material"></param>
        protected override void CopyTo(D2DComponent component)
        {
            base.CopyTo(component);

            D2DAnimatedSpriteComponent comp = (D2DAnimatedSpriteComponent)component;            

            foreach (string key in Animations.Keys)
            {
                comp.Animations.Add(key, (D2DFrameAnimation)Animations[key].Clone());
            }

            comp.CurrentAnimationName = this.currentAnimation;
        }
    }
}
